/*
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/
#ifndef __ERROR_H__
#define __ERROR_H__

#include <openssl/err.h>
#include <iostream>
#include <fstream>
#include <sys/time.h>
#include <time.h>

/**
 * use X-macro, see http://en.wikipedia.org/wiki/C_preprocessor
 * 
 */ 
#define  ERROR_DEFS \
	ERR_CODE(ERR_NONE, "No Error") \
	ERR_CODE(ERR_SW, " software error") \
	ERR_CODE(ERR_UNIQUE, " must be unique key") \
	ERR_CODE(ERR_DELETE, " object deleletion error") \
	ERR_CODE(ERR_OUT_OF_RANGE, " Out ot range error") \
	ERR_CODE(ERR_CMDLINE, " command line error") \
	ERR_CODE(ERR_NOTENOUGH_DATA, " not enough data") \
	ERR_CODE(ERR_NOTDEFINED, " not defined") 
		

typedef enum {
#define ERR_CODE(val, desc) val,
	ERROR_DEFS
#undef ERR_CODE
	ERR_UNKNOWN
}ErrCode_t;

const static char* ErrCodeDescription[] = {
#define ERR_CODE(val, desc) desc,
	ERROR_DEFS
#undef ERR_CODE
	"Unknown error"	
};
                               

static ErrCode_t __handleError(ErrCode_t code, const char* file, int line)
{
	if (code != ERR_NONE) { 
		std::cerr << "|" <<  __FILE__ << "|" << __LINE__ << "|" <<  ErrCodeDescription[code]; 
	}
	return code;
}



#define ERR(code)		__handleError(code, __FILE__, __LINE__)

#define ERROUT  	std::cerr
#define NEWLN       "Command Parser: "
#define ENDLN		std::endl

#ifdef DEBUG

#define  DBGOUT    std::cout

#else 
class nullout : public std::ofstream {
public:
     nullout() {};
     inline nullout & operator<< (nullout& o) {
          return o;
     }
     virtual ~nullout() {};
};

#define DBGOUT 		nullout

}
#endif

#endif


